package org.lagou.edu.stock;

import com.alibaba.dubbo.spring.boot.annotation.EnableDubboConfiguration;
import org.lagou.edu.rpc.IStockService;
import org.lagou.edu.stock.model.Stock;
import org.lagou.edu.stock.service.StockService;
import org.lagou.edu.stock.task.ListenBinlogTask;
import org.lagou.edu.stock.utils.RedisUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;

import java.io.IOException;
import java.util.concurrent.CountDownLatch;

/**
 * 实现下单扣减库存，管理端编辑库存时，Mysql 和 Redis的同步
 * @Author 咖啡杯里的茶
 * @date 2022/7/16
 */
@SpringBootApplication
@EnableDubboConfiguration
public class StockManageMain {

	private long shopId = 0L;
	private long quantity = 0L;

	private static IStockService stockService = new StockService();

	public static void main(String[] args) throws IOException, InterruptedException {
		ConfigurableApplicationContext applicationContext = SpringApplication.run(StockManageMain.class, args);

		stockService = applicationContext.getBean(IStockService.class);

		StockManageMain stockManageMain = new StockManageMain();
		// 第一种方式，直接在更新完mysql 之后更新 redis
		//stockSyncMain.directSync();

//		// 启动监听 binlog 的线程
		new Thread(new ListenBinlogTask()).start();
		stockManageMain.syncByBinlog();

		System.out.println("服务启动完成..");
		new CountDownLatch(1).await();	// hold住进程
	}

	/**
	 * 	第一种同步方式，直接在 Mysql 中扣减库存在，查询新的库存数据，然后同步到 redis 中
	 */
	public void directSync() {
		stockService.deductionStock(shopId, quantity);
		long stockQuantity = stockService.queryStock(shopId);
		RedisUtil.syncStock(shopId, stockQuantity);
	}

	/**
	 * 第二种同步方式，解析 Mysql 中的binlog， 然后将数据解析出来同步到 Redis 中
	 * binlog中会包含库存表所在库的所有数据，我们只需要同步库存表的数据到 redis 中即可
	 * https://github.com/shyiko/mysql-binlog-connector-java  参考该工具来解析binlog 数据
	 * 参考文档： https://developer.51cto.com/article/671585.html
	 */
	public void syncByBinlog() {
		// 只需要管 mysql 扣减库存的操作即可，同步到redis的步骤通过监控mysql的binlog 来实现
		stockService.deductionStock(shopId, quantity);
	}
}
